package model;

import static org.junit.Assert.*;

import java.security.SecureRandom;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class CroupierTest
{
	private static Player playersWithTheSameBets[];
	private static Player playersWithDifferentBets[];
	private static Deck sDeck1;
	private static Deck sDeck2;
	
	Player[] players;
	Deck deck;
	int playersAmount;
	int maxBet;
	static SecureRandom Generator;
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception
	{
		Generator = new SecureRandom();
		
		sDeck1 = new Deck();
		sDeck2 = new Deck();
		playersWithTheSameBets = new Player[7];
		playersWithDifferentBets = new Player[7];
		for(int i=1; i<=6; i++){
			playersWithTheSameBets[i]= new Player("name" + Integer.toString(i), i, 100, sDeck1);
			playersWithDifferentBets[i]= new Player("name"+ Integer.toString(i), i, 100, sDeck2);
		
		}
		playersWithTheSameBets[1].setBet(30);
		playersWithTheSameBets[1].setStatus(Player.PLAYER_OUT_OF_GAME);
		playersWithTheSameBets[2].setBet(10);
		playersWithTheSameBets[2].setStatus(Player.PLAYER_OUT_OF_GAME);
		playersWithTheSameBets[3].setBet(20);
		playersWithTheSameBets[3].setStatus(Player.PLAYER_PLAYED_ALLIN);
		playersWithTheSameBets[4].setBet(30);
		playersWithTheSameBets[4].setStatus(Player.PLAYER_IN_GAME);
		playersWithTheSameBets[5].setBet(30);
		playersWithTheSameBets[5].setStatus(Player.PLAYER_IN_GAME);
		playersWithTheSameBets[6].setBet(30);
		playersWithTheSameBets[6].setStatus(Player.PLAYER_PLAYED_ALLIN);
		
		playersWithDifferentBets[1].setBet(30);
		playersWithDifferentBets[1].setStatus(Player.PLAYER_OUT_OF_GAME);
		playersWithDifferentBets[2].setBet(30);
		playersWithDifferentBets[2].setStatus(Player.PLAYER_OUT_OF_GAME);
		playersWithDifferentBets[3].setBet(20);
		playersWithDifferentBets[3].setStatus(Player.PLAYER_PLAYED_ALLIN);
		playersWithDifferentBets[4].setBet(30);
		playersWithDifferentBets[4].setStatus(Player.PLAYER_IN_GAME);
		playersWithDifferentBets[5].setBet(40);
		playersWithDifferentBets[5].setStatus(Player.PLAYER_IN_GAME);
		playersWithDifferentBets[6].setBet(20);
		playersWithDifferentBets[6].setStatus(Player.PLAYER_PLAYED_ALLIN);
		
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception
	{
		for(int i=1; i<=6; i++){
			playersWithTheSameBets[i]= null;
			playersWithDifferentBets[i]= null;
		}
		playersWithDifferentBets = null;
		playersWithTheSameBets = null;
		sDeck1 = null;
		sDeck2 = null;
	}

	@Before
	public void setUp() throws Exception
	{
		playersAmount = Generator.nextInt(5)+2;// Might be 2,3,4,5,6
		players = new Player[playersAmount+1];
		deck = new Deck();
		maxBet = 0;
		for(int i=1; i<players.length; i++) {
			players[i] = new Player("name" + Integer.toString(i), i, 3000,deck);
			players[i].setStatus(Generator.nextInt(3)-1);
			players[i].setBet(Generator.nextInt(3001));
			if (players[i].getBet()>maxBet) 
				maxBet = players[i].getBet();
			players[i].setPlayersCoins(3000-players[i].getBet());
		}
		players[1].setStatus(Player.PLAYER_IN_GAME);

		
	}

	@After
	public void tearDown() throws Exception
	{
		for(int i=1; i<players.length; i++) {
			players[i] = null;
		}
		players = null;
		deck = null;
		
	}

	@Test
	public void testWhichPlayerNext2Allin()
	{
		int next = 0;
		System.out.println("playersAmount=" + playersAmount);
		for (int i=1; i<=playersAmount; i++) {
			System.out.println("Status:" +players[i].getStatus());
		}
		for(int i=0; i<=playersAmount ; i++) {
			try{
				next = Croupier.whichPlayerNext2(1, players, true);
			} catch (GameException e){}
			System.out.println(next);
			if (next!=1)
				players[next].setStatus(Player.PLAYER_OUT_OF_GAME);
		}
		assertEquals(1, next);
	}
	public void testWhichPlayerNext2WithoutAllin()
	{
		int next = 0;
		System.out.println("playersAmount=" + playersAmount);
		for (int i=1; i<=playersAmount; i++) {
			System.out.println("Status:" +players[i].getStatus());
		}
		for(int i=0; i<=playersAmount ; i++) {
			try{
				next = Croupier.whichPlayerNext2(1, players, false);
			} catch (GameException e){}
			System.out.println(next);
			if (next!=1)
				players[next].setStatus(Player.PLAYER_OUT_OF_GAME);
		}
		assertEquals(1, next);
	}

	@Test
	public void testWhichPlayerNext()
	{
		for(int i=2;i<=6; i++) {
			System.out.println("i=" + i + " next=" +Croupier.whichPlayerNext(i, i));
			assertEquals(1, Croupier.whichPlayerNext(i, i));
		}
	}

	@Test
	public void testDrawDealer()
	{
		for(int i=2; i<=6; i++){
			for(int j=0; j<100; j++){
				int whoDealer = Croupier.drawDealer(i);
				assertTrue(1<=whoDealer && whoDealer<=i);
			}
		} 
	}

	@Test
	public void testPossibleMoves()
	{
		//pierwsza runda i brak kasy by przebić
			assertEquals("CF", Croupier.possibleMoves(10, 10,false,20, 1));
			assertEquals("CRF",Croupier.possibleMoves(20,30 ,false, 30, 1));
			assertEquals("FA",Croupier.possibleMoves(20,5 ,false, 30, 1));
			assertEquals("RF",Croupier.possibleMoves(30,5 ,false, 30, 1));
			assertEquals("FA",Croupier.possibleMoves(30,0 ,false, 30, 1));
			//kolejne rundy
			assertEquals("HBF", Croupier.possibleMoves(20, 10,false,20, 2));
			assertEquals("HF",Croupier.possibleMoves(20,0 ,false, 20, 2));
			assertEquals("CF",Croupier.possibleMoves(20,10 ,true, 30, 2));
			assertEquals("FA",Croupier.possibleMoves(20,5 ,true, 30, 2));
			assertEquals("RF",Croupier.possibleMoves(30,5 ,true, 30, 2));
			assertEquals("FA",Croupier.possibleMoves(30,0 ,true, 30, 2));
		
	}

	@Test
	public void testHavePlayersTheSameBetsPlayerArray()
	{
		assertTrue(Croupier.havePlayersTheSameBets(playersWithTheSameBets));
		assertFalse(Croupier.havePlayersTheSameBets(playersWithDifferentBets));
	
	}

	
}
